package com.miracle9.game.server.message;

import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;
import org.apache.mina.filter.codec.demux.MessageDecoder;
import org.apache.mina.filter.codec.demux.MessageDecoderResult;

public class MessageDecoderUtil implements MessageDecoder
{
  private static Logger logger = Logger.getLogger(MessageDecoderUtil.class.getName());
  
  public void finishDecode(IoSession arg0, ProtocolDecoderOutput arg1)
    throws Exception
  {}
  
  public MessageDecoderResult decodable(IoSession arg0, IoBuffer in)
  {
    try
    {
      in.mark();
      
      int datalen = (int)in.getUnsignedInt();
      if (datalen > 65536)
      {
        logger.error("session:" + arg0.getRemoteAddress() + " is asummed to be attack,datalen" + datalen);
        arg0.close(true);
        return MessageDecoderResult.NOT_OK;
      }
      if (datalen == 1014001516)
      {
        byte[] requestBytes = new byte[23];
        in.clear();
        in.get(requestBytes);
        
        String msg = new String(requestBytes).trim();
        if (msg.equals("<policy-file-request/>")) {
          return MessageDecoderResult.OK;
        }
        return MessageDecoderResult.NEED_DATA;
      }
      if (datalen == 1952937823)
      {
        byte[] requestBytes = new byte[62];
        in.clear();
        in.get(requestBytes);
        
        String msg = new String(requestBytes).trim();
        if (msg.indexOf("tgw_l7_forward") > -1) {
          return MessageDecoderResult.OK;
        }
        return MessageDecoderResult.NEED_DATA;
      }
      in.reset();
    //  logger.info("in.remaining() = :" + in.remaining()+ "datalen" + datalen);
      if (in.remaining() - 4 >= datalen) {
        return MessageDecoderResult.OK;
      }
      return MessageDecoderResult.NEED_DATA;
    }
    catch (Exception e)
    {
      logger.error("data is un-decodable", e);
    }
    return MessageDecoderResult.OK;
  }
  
  public MessageDecoderResult decode(IoSession arg0, IoBuffer in, ProtocolDecoderOutput out)
    throws Exception
  {
    int datalen;
    for (;;)
    {
      in.mark();
      datalen = 0;
      if (in.remaining() >= 4)
      {
        datalen = (int)in.getUnsignedInt();
        if (datalen == 0) {
          throw new Exception("data length is 0");
        }
        in.reset();
      }
      else
      {
        if (in.remaining() == 0) {
          return MessageDecoderResult.OK;
        }
        return MessageDecoderResult.NEED_DATA;
      }
      if (datalen == 0) {
        throw new Exception("data length is 0");
      }
      if (in.remaining() - 4 < datalen) {
        break;
      }
      byte[] data = new byte[datalen + 4];
      in.get(data);
      IoBuffer bf = IoBuffer.wrap(data);
      out.write(bf);
    }
    if (datalen == 1014001516)
    {
      byte[] data = new byte[23];
      in.get(data);
      IoBuffer bf = IoBuffer.wrap(data);
      out.write(bf);
      
      return MessageDecoderResult.OK;
    }
    if (datalen == 1952937823)
    {
      byte[] data = new byte[62];
      in.get(data);
      IoBuffer bf = IoBuffer.wrap(data);
      out.write(bf);
      
      return MessageDecoderResult.OK;
    }
    return MessageDecoderResult.NEED_DATA;
  }
}
